\defmodule {BrownianMotion}

This class represents a \emph{Brownian motion} process $\{X(t) : t \geq 0 \}$,
sampled at times $0 = t_0 < t_1 < \cdots < t_d$.
This process obeys the stochastic differential equation
\begin{equation}
   dX(t) = \mu dt + \sigma dB(t),
                                               \label{eq:Brownian-motion}
\end{equation}
with initial condition $X(0)= x_0$,
where $\mu$ and $\sigma$ are the drift and volatility parameters,
and $\{B(t),\, t\ge 0\}$ is a standard Brownian motion
(with drift 0 and volatility 1).
This process has stationary and independent increments over disjoint
time intervals (it is a L\'evy process) and the increment over an interval
of length $t$ is normally distributed with mean $\mu t$ and variance $\sigma^2 t$.

In this class, this process is generated using the sequential (or random walk)
technique:  $X(0)=x_0$ and
\begin{equation}
   X(t_j) - X(t_{j-1}) = \mu(t_j - t_{j-1}) + \sigma \sqrt{t_j - t_{j-1}} Z_j
                                    \label{eq:Brownian-motion-sequential}
\end{equation}
where $Z_j \sim N(0,1)$.

\bigskip\hrule\bigskip

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{code}
\begin{hide}
/*
 * Class:        BrownianMotion
 * Description:  
 * Environment:  Java
 * Software:     SSJ 
 * Copyright (C) 2001  Pierre L'Ecuyer and Universite de Montreal
 * Organization: DIRO, Universite de Montreal
 * @author       
 * @since

 * SSJ is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License (GPL) as published by the
 * Free Software Foundation, either version 3 of the License, or
 * any later version.

 * SSJ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * A copy of the GNU General Public License is available at
   <a href="http://www.gnu.org/licenses">GPL licence site</a>.
 */
\end{hide}
package umontreal.iro.lecuyer.stochprocess;\begin{hide}
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.probdist.*;
import umontreal.iro.lecuyer.randvar.*;

\end{hide}

public class BrownianMotion extends StochasticProcess \begin{hide} {
    protected NormalGen    gen;
    protected double       mu,
                           sigma;
    // Precomputed values for standard BM
    protected double[]     mudt,
                           sigmasqrdt;
\end{hide}
\end{code}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection* {Constructors}
\begin{code}

   public BrownianMotion (double x0, double mu, double sigma,
                          RandomStream stream)\begin{hide} {
        this (x0, mu, sigma, new NormalGen (stream));
    }\end{hide}
\end{code}
\begin{tabb} Constructs a new \texttt{BrownianMotion} with
parameters $\mu =$ \texttt{mu}, $\sigma =$ \texttt{sigma} and initial value
$X(t_{0}) =$ \texttt{x0}.
The normal variates $Z_j$ in (\ref{eq:Brownian-motion-sequential}) will be
generated by inversion using \texttt{stream}.
\end{tabb}
\begin{code}

   public BrownianMotion (double x0, double mu, double sigma, NormalGen gen)\begin{hide} {
        this.mu    = mu;
        this.sigma = sigma;
        this.x0    = x0;
        this.gen   = gen;
    }\end{hide}
\end{code}
\begin{tabb} Constructs a new \texttt{BrownianMotion} with parameters $\mu =$
\texttt{mu}, $\sigma =$ \texttt{sigma} and initial value $X(t_{0}) =$ \texttt{x0}.
Here, the normal variate generator
\externalclass{umontreal.iro.lecuyer.randvar}{NormalGen} is specified
directly instead of specifying the stream and using inversion.
The normal generator \texttt{gen} can use another method than inversion.
\end{tabb}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsubsection* {Methods}
\begin{code} \begin{hide}

   public double nextObservation() {
        double x = path[observationIndex];
        x += mudt[observationIndex]
             + sigmasqrdt[observationIndex] * gen.nextDouble();
        observationIndex++;
        path[observationIndex] = x;
        return x;
    }

\end{hide}
   public double nextObservation (double nextTime) \begin{hide} {
        // This method is useful for generating variance gamma processes
        double x = path[observationIndex];
        double previousTime = t[observationIndex];
        observationIndex++;
        t[observationIndex] = nextTime;
        double dt = nextTime - previousTime;
        x += mu * dt + sigma * Math.sqrt (dt) * gen.nextDouble();
        path[observationIndex] = x;
        return x;
    }\end{hide}
\end{code}
\begin{tabb} Generates and returns the next observation at time $t_{j+1} =$
 \texttt{nextTime}. It uses the previous observation time $t_{j}$ defined earlier
(either by this method or by \texttt{setObservationTimes}),
as well as the value of the previous observation $X(t_j)$.
\emph{Warning}: This method will reset the observations time $t_{j+1}$
for this process to \texttt{nextTime}. The user must make sure that
the $t_{j+1}$ supplied is $\geq t_{j}$.
\end{tabb}
\begin{code}

   public double nextObservation (double x, double dt) \begin{hide} {
        x += mu * dt + sigma * Math.sqrt (dt) * gen.nextDouble();
        return x;
    }\end{hide}
\end{code}
\begin{tabb} Generates an observation of the process in \texttt{dt} time units,
assuming that the process has value $x$ at the current time.
Uses the process parameters specified in the constructor.
Note that this method does not affect the sample path of the process
stored internally (if any).
\end{tabb}
\begin{code}\begin{hide}

   public double[] generatePath() {
        double x = x0;
        for (int j = 0; j < d; j++) {
            x += mudt[j] + sigmasqrdt[j] * gen.nextDouble();
            path[j + 1] = x;
        }
        observationIndex   = d;
        observationCounter = d;
        return path;
    }\end{hide}

   public double[] generatePath (double[] uniform01) \begin{hide} {
        double x = x0;
        for (int j = 0; j < d; j++) {
            x += mudt[j] + sigmasqrdt[j] * NormalDist.inverseF01(uniform01[j]);
            path[j + 1] = x;
        }
        observationIndex   = d;
        observationCounter = d;
        return path;
    }\end{hide}
\end{code}
\begin{tabb} Same as generatePath(), but a vector of uniform random numbers
must be provided to the method.  These uniform random numbers are used
to generate the path.
\end{tabb}
\begin{code}\begin{hide}

   public double[] generatePath (RandomStream stream) {
        gen.setStream (stream);
        return generatePath();
    }\end{hide}

   public void setParams (double x0, double mu, double sigma) \begin{hide} {
        this.x0    = x0;
        this.mu    = mu;
        if (sigma <= 0)
           throw new IllegalArgumentException ("sigma <= 0");
        this.sigma = sigma;
        if (observationTimesSet) init(); // Otherwise not needed.
    }\end{hide}
\end{code}
\begin{tabb}
Resets the parameters $X(t_{0}) = \texttt{x0}$, $\mu = \texttt{mu}$ and
$\sigma = \texttt{sigma}$ of the process.
\emph{Warning}: This method will recompute some quantities stored internally,
which may be slow if called too frequently.
\end{tabb}
\begin{code}

   public void setStream (RandomStream stream) \begin{hide} { gen.setStream (stream); }\end{hide}
\end{code}
\begin{tabb}
Resets the random stream of the normal generator to \texttt{stream}.
\end{tabb}
\begin{code}

   public RandomStream getStream() \begin{hide} { return gen.getStream (); }\end{hide}
\end{code}
\begin{tabb}
Returns the random stream of the normal generator.
\end{tabb}
\begin{code}

   public double getMu() \begin{hide} { return mu; }\end{hide}
\end{code}
\begin{tabb}
Returns the value of $\mu$.
\end{tabb}
\begin{code}

   public double getSigma() \begin{hide} { return sigma; }\end{hide}
\end{code}
\begin{tabb}
Returns the value of $\sigma$.
\end{tabb}
\begin{code}

   public NormalGen getGen() \begin{hide} { return gen; }\end{hide}
\end{code}
\begin{tabb}
Returns the normal random variate generator used.
The \externalclass{umontreal.iro.lecuyer.rng}{RandomStream}
used by that generator can be changed via
\texttt{getGen().setStream(stream)}, for example.
\end{tabb}
\begin{code} \begin{hide}

    // This is called by setObservationTimes to precompute constants
    // in order to speed up the path generation.
   protected void init() {
        super.init();
        mudt       = new double[d];
        sigmasqrdt = new double[d];
        for (int j = 0; j < d; j++) {
            double dt     = t[j+1] - t[j];
            mudt[j]       = mu * dt;
            sigmasqrdt[j] = sigma * Math.sqrt (dt);
        }
     }

} \end{hide}
\end{code}
